package com.panovue.dataextraction.reader;

import cn.edu.hfut.dmic.webcollector.model.CrawlDatum;
import cn.edu.hfut.dmic.webcollector.model.CrawlDatums;
import cn.edu.hfut.dmic.webcollector.model.Page;
import cn.hutool.core.io.FileUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.panovue.dataextraction.ReaderUtil;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.File;

@Slf4j
public class ThermoReader extends AbstractReader {

    public ThermoReader() {
        super("thermo", true);
    }

    public ThermoReader(String key) {
        super("thermo", true);
        this.key = key;

        baseUrl = "https://www.thermofisher.cn/";
        baseDir += key + File.separator + "thermo" + File.separator;

        // 设置线程数
        setThreads(5);
        addSeedAndReturn(baseUrl + "search/results?query=" + key + "&focusarea=搜索全部或下列指定分类" + key).type("list");

        getConf().setExecuteInterval(3000);

        buildDriver(true);

        // 开始爬取
        try {
            start(20);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void visit(Page page, CrawlDatums next) {
        data.set("应用类型", "");
        data.set("种属来源", "");
        data.set("反应种属", "");
        data.set("克隆属性", "");
        data.set("着色样式", "");
        data.set("稀释倍数", "");
        data.set("染色例图，对应的样本信息， 酸碱修复条件", "");
        data.set("参考文献情况", "");
    }

    @MatchType(types = "list")
    public void list(Page page, CrawlDatums next) {
        Element element = page.select("#result-cards a").get(1);
        String href = element.attr("href");
        next.addAndReturn(href).type("details");
    }

    @MatchType(types = "details")
    public void details(Page page, CrawlDatums next) {
        JSONObject details = new JSONObject();

        Elements tables = page.select(".product-detail-section.tested-app-section.new-tbl-design.product-detail-section.table-spec");

        JSONArray table1 = new JSONArray();

        Elements table1_body = tables.first().select(".product-container-body");
        for (int i = 0; i < table1_body.size(); i++) {
            JSONObject jsonObject = new JSONObject();
            Elements select = table1_body.get(i).select(".product-item");
            jsonObject.set("应用", select.get(0).text());
            jsonObject.set("建议稀释比", select.get(1).text());
            jsonObject.set("已发表文章", page.url() + select.get(2).select("a").attr("href"));
            table1.add(jsonObject);
        }
        data.set("table1", table1);

        JSONArray table2 = new JSONArray();

        Elements table2_body = tables.get(1).select(".product-container-body.pcb1-2");
        for (int i = 0; i < table2_body.size(); i++) {
            JSONObject jsonObject = new JSONObject();
            Elements select = table2_body.get(i).select(".product-item");
            jsonObject.set(select.get(0).text(), select.get(1).text());
            table2.add(jsonObject);
        }
        data.set("table2", table2);

        JSONArray images = new JSONArray();
        JSONArray antibody_testing_data = JSONUtil.parseObj(page.select("#image-gallery").select(".gal-cntr.container").attr("media-items")).getJSONArray("Antibody Testing Data");
        for (Object antibody_testing_datum : antibody_testing_data) {
            JSONObject image = new JSONObject();
            JSONObject jsonObject = JSONUtil.parseObj(antibody_testing_datum);
            String imageName = jsonObject.getStr("imageName");
            String imageUrlFullSize = jsonObject.getStr("imageUrlFullSize");
            String title = jsonObject.getStr("title");
            String description = jsonObject.getStr("description");
            image.set("title", title);
            image.set("imageName", imageName);
            image.set("description", description);
            image.set("imageUrlFullSize", imageUrlFullSize);
            images.add(image);

            ReaderUtil.saveFile(imageUrlFullSize, baseDir + imageName);
        }
        data.set("images", images);

        String text = page.select(".hidden-sku h2").text();
        String url = "https://www.thermofisher.cn/order/genome-database/productReferences?productId=" + text + "&productType=antibody";
        JSONObject jsonObject = JSONUtil.parseObj(HttpUtil.get(url));
        JSONArray citationApplications = jsonObject.getJSONArray("citationApplications");
        JSONArray references = new JSONArray();
        for (Object citationApplication : citationApplications) {
            JSONObject object = JSONUtil.parseObj(citationApplication);
            JSONArray citations = object.getJSONArray("citations");
            for (Object citation : citations) {
                JSONObject reference = new JSONObject();
                JSONObject obj = JSONUtil.parseObj(citation);
                reference.set("title", obj.getStr("title"));
                reference.set("literatureId", obj.getInt("literatureId"));
                reference.set("url", obj.getStr("url"));
                references.add(reference);
            }
        }
        data.set("参考文献", references);
    }

    @MatchType(types = "literatures")
    public void literatures(Page page, CrawlDatums next) {
        JSONArray literatures = new JSONArray();
        for (Object object : page.select("")) {
            JSONObject jsonObject = JSONUtil.parseObj(object);
            String title = jsonObject.getStr("Title");
            String url = "https://pubmed.ncbi.nlm.nih.gov/" + jsonObject.getInt("PubmedID");
            jsonObject.set(title, url);
            literatures.add(jsonObject);
        }
        data.set("文献", literatures);
    }

    @MatchCode(codes = {301, 302, 307})
    public void retry(Page page, CrawlDatums next) {
        CrawlDatum crawlDatum = new CrawlDatum();
        crawlDatum.url(page.location());
        crawlDatum.type(page.matchType("list") ? "list" : "details");
        crawlDatum.key(crawlDatum.getExecuteTime() + page.url());
        next.addAndReturn(crawlDatum);
    }

    @Override
    public void afterStop() {
        if (driver != null) {
            driver.quit();
        }
        FileUtil.writeUtf8String(data.toString(), baseDir + File.separator + key + ".json");
        log.info("thermo 数据爬取完成");
    }

    @Override
    public void execute(CrawlDatum datum, CrawlDatums next) throws Exception {
        super.execute(datum, next);
        log.info("url {} code {}", datum.url(), datum.code());
    }

    @Override
    public Reader buildReader(String key) {
        return new ThermoReader(key);
    }
}
